#include "Queue.h"

void QueueInit(Queue* pq)
{
    assert(pq);
    pq->head = pq->tail = nullptr;
    pq->size = 0;
}

void QueueDestory(Queue* pq)
{
    assert(pq);
    while (pq->head)
    {
        QueueNode* del = pq->head;
        pq->head = pq->head->next;
        free(del);
    }

    pq->head = pq->tail = nullptr;
    pq->size = 0;
}

void QueuePush(Queue* pq, QDataType val)
{
    assert(pq);

    QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    assert(newNode);
    newNode->val = val;
    newNode->next = nullptr;

    if (!pq->tail)
        pq->head = pq->tail = newNode;
    else
    {
        pq->tail->next = newNode;
        pq->tail = newNode;
    }
    pq->size++;
}

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));

    QueueNode* del = pq->head;
    if (pq->head == pq->tail)
        pq->tail = pq->head = nullptr;
    else pq->head = del->next;

    free(del);
    del = nullptr;
    pq->size--;
}

bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->head == nullptr && pq->tail == nullptr;
}

int QueueSize(Queue* pq)
{
    assert(pq);
    return pq->size;
}

QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(QueueSize(pq));
    return pq->head->val;
}

QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(QueueSize(pq));
    return pq->tail->val;
}